"""
表格组件，实现类似Element Plus的表格样式和功能
"""
from PyQt5.QtWidgets import (QTableView, QAbstractItemView, QHeaderView, 
                            QStyledItemDelegate, QStyleOptionViewItem, QStyle)
from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex, QVariant, pyqtSignal
from PyQt5.QtGui import QPainter, QColor
from component.theme import Theme


class TableModel(QAbstractTableModel):
    """表格数据模型"""
    
    def __init__(self, data=None, headers=None, parent=None):
        """
        初始化表格数据模型
        
        Args:
            data: 表格数据，二维列表
            headers: 表头数据，列表
            parent: 父组件
        """
        super().__init__(parent)
        self._data = data if data is not None else []
        self._headers = headers if headers is not None else []
    
    def rowCount(self, parent=QModelIndex()):
        """返回行数"""
        return len(self._data)
    
    def columnCount(self, parent=QModelIndex()):
        """返回列数"""
        return len(self._headers) if self._headers else (len(self._data[0]) if self._data else 0)
    
    def data(self, index, role=Qt.DisplayRole):
        """返回指定索引的数据"""
        if not index.isValid():
            return QVariant()
        
        if role == Qt.DisplayRole or role == Qt.EditRole:
            return self._data[index.row()][index.column()]
        
        return QVariant()
    
    def headerData(self, section, orientation, role=Qt.DisplayRole):
        """返回表头数据"""
        if role == Qt.DisplayRole:
            if orientation == Qt.Horizontal and section < len(self._headers):
                return self._headers[section]
            elif orientation == Qt.Vertical:
                return section + 1
        
        return QVariant()
    
    def setData(self, index, value, role=Qt.EditRole):
        """设置数据"""
        if not index.isValid() or role != Qt.EditRole:
            return False
        
        self._data[index.row()][index.column()] = value
        self.dataChanged.emit(index, index)
        return True
    
    def flags(self, index):
        """返回项的标志"""
        if not index.isValid():
            return Qt.NoItemFlags
        
        return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
    
    def insertRows(self, position, rows, parent=QModelIndex()):
        """插入行"""
        self.beginInsertRows(parent, position, position + rows - 1)
        
        for i in range(rows):
            self._data.insert(position, ['' for _ in range(self.columnCount())])
        
        self.endInsertRows()
        return True
    
    def removeRows(self, position, rows, parent=QModelIndex()):
        """删除行"""
        self.beginRemoveRows(parent, position, position + rows - 1)
        
        for i in range(rows):
            self._data.pop(position)
        
        self.endRemoveRows()
        return True
    
    def setHeaders(self, headers):
        """设置表头"""
        self._headers = headers
        self.headerDataChanged.emit(Qt.Horizontal, 0, len(headers) - 1)
    
    def setData2D(self, data):
        """设置表格数据"""
        self.beginResetModel()
        self._data = data
        self.endResetModel()


class TableItemDelegate(QStyledItemDelegate):
    """表格项代理，用于自定义表格项的绘制"""
    
    def paint(self, painter, option, index):
        """绘制表格项"""
        # 绘制选中项的背景
        if option.state & QStyle.State_Selected:
            painter.fillRect(option.rect, QColor(Theme.PRIMARY_LIGHTER))
        
        # 调用父类方法绘制内容
        super().paint(painter, option, index)


class Table(QTableView):
    """
    表格组件，支持多种样式和功能
    
    信号:
        row_clicked(int): 行被点击时发出，参数为行索引
        cell_clicked(int, int): 单元格被点击时发出，参数为行索引和列索引
        selection_changed(): 选择改变时发出
    """
    
    row_clicked = pyqtSignal(int)
    cell_clicked = pyqtSignal(int, int)
    selection_changed = pyqtSignal()
    
    def __init__(self, parent=None, data=None, headers=None, stripe=True, 
                 border=True, highlight_current_row=True):
        """
        初始化表格
        
        Args:
            parent: 父组件
            data: 表格数据，二维列表
            headers: 表头数据，列表
            stripe: 是否显示斑马纹
            border: 是否显示边框
            highlight_current_row: 是否高亮当前行
        """
        super().__init__(parent)
        
        self._stripe = stripe
        self._border = border
        self._highlight_current_row = highlight_current_row
        
        # 设置模型
        self._model = TableModel(data, headers, self)
        self.setModel(self._model)
        
        # 设置代理
        self.setItemDelegate(TableItemDelegate())
        
        # 设置表格属性
        self.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.setSelectionMode(QAbstractItemView.SingleSelection)
        self.setAlternatingRowColors(stripe)
        self.setShowGrid(True)
        self.setGridStyle(Qt.SolidLine)
        self.setSortingEnabled(True)
        self.setCornerButtonEnabled(False)
        self.setWordWrap(False)
        self.setTextElideMode(Qt.ElideRight)
        
        # 设置表头
        self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.horizontalHeader().setHighlightSections(False)
        self.horizontalHeader().setDefaultAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.horizontalHeader().setSortIndicatorShown(True)
        
        self.verticalHeader().setVisible(False)
        self.verticalHeader().setDefaultSectionSize(40)
        
        # 设置样式
        self.setStyleSheet(Theme.get_style_sheet("table"))
        
        # 连接信号
        self.clicked.connect(self._on_clicked)
        self.selectionModel().selectionChanged.connect(self._on_selection_changed)
    
    def _on_clicked(self, index):
        """处理点击事件"""
        self.row_clicked.emit(index.row())
        self.cell_clicked.emit(index.row(), index.column())
    
    def _on_selection_changed(self, selected, deselected):
        """处理选择改变事件"""
        self.selection_changed.emit()
    
    def set_data(self, data, headers=None):
        """设置表格数据"""
        if headers is not None:
            self._model.setHeaders(headers)
        
        self._model.setData2D(data)
    
    def get_data(self):
        """获取表格数据"""
        return self._model._data
    
    def get_selected_row(self):
        """获取选中行的索引"""
        indexes = self.selectionModel().selectedRows()
        if indexes:
            return indexes[0].row()
        return -1
    
    def get_selected_rows(self):
        """获取所有选中行的索引"""
        return [index.row() for index in self.selectionModel().selectedRows()]
    
    def add_row(self, row_data=None):
        """添加行"""
        row_count = self._model.rowCount()
        self._model.insertRows(row_count, 1)
        
        if row_data:
            for col, data in enumerate(row_data):
                if col < self._model.columnCount():
                    self._model.setData(self._model.index(row_count, col), data)
    
    def remove_row(self, row):
        """删除行"""
        self._model.removeRows(row, 1)
    
    def remove_selected_rows(self):
        """删除选中的行"""
        rows = sorted(self.get_selected_rows(), reverse=True)
        for row in rows:
            self.remove_row(row)
    
    def clear(self):
        """清空表格"""
        self._model.setData2D([])
    
    def set_column_width(self, column, width):
        """设置列宽"""
        self.horizontalHeader().setSectionResizeMode(column, QHeaderView.Fixed)
        self.horizontalHeader().resizeSection(column, width)
    
    def set_row_height(self, row, height):
        """设置行高"""
        self.verticalHeader().setSectionResizeMode(row, QHeaderView.Fixed)
        self.verticalHeader().resizeSection(row, height) 